\cleardoublepage
\sectionnonum{附录}

\begin{lstlisting}[
  captionpos=b,
  caption={WebSocket 服务器示例}, 
  label={websocket-server-example}
]
#include "server/websocket_server.hpp"

#include <filesystem>
#include <fstream>

int main(int, char**) {
    logger::get_instance().set_output_file_path("./log/server");

    std::filesystem::create_directory("recv");

    websocket_server s(1234);
    win::socket sock;

    s.register_accept_hook(
      [&](const auto& conn) { sock = conn.sock; });

    s.register_recv_hook([&](
        win::socket, const auto& address, auto frame) {
        linfo("received websocket data from: " 
            << nonstd::to_string(address) << "\n" 
            << frame.description());

        if (frame.opcode == BINARY_FRAME) {
            auto file = "recv/" 
              + std::to_string(now_in_i64()) + ".out";
            linfo("writing binary frame to " << file);
            std::ofstream fout(file, std::ios::out | 
               std::ios::app | std::ios::binary);
            fout.write(frame.buffer.data(), frame.buffer.size());
        }
    }); 
    s.start();
    while (true) {
        std::string str;
        std::cin >> str;
        if (str == "close") {
            s.stop();
            break;
        }
        if (!s.send(sock, std::vector(str.begin(), str.end()), 
          TEXT_FRAME)) {
            lwarn("send data to server failed.");
            break;
        }
    }
    return 0;
}
\end{lstlisting}

\begin{lstlisting}[
  captionpos=b,
  caption={WebSocket 客户端示例}, 
  label={websocket-client-example}
]
#include "client/client.hpp"
#include "client/websocket_client.hpp"

#include <chrono>
#include <filesystem>
#include <fstream>
#include <iostream>
int main() {
    logger::get_instance().set_output_file_path("./log/client");
    websocket_client c;
    if (!c.connect("127.0.0.1", 1234)) {
        lwarn("connect to websocket server failed.");
        return 0;
    }
    while (true) {
        std::string str;
        std::cin >> str;
        if (!c.alive()) {
            break;
        }
        if (str == "close") {
            c.close();
            break;
        } else if (str == "file") {
            std::cin >> str;
            if (!std::filesystem::exists(str)) {
                lwarn("cannot find file " << str);
                continue;
            }
            std::ifstream fin(str, std::ios::binary | std::ios::ate);
            std::vector<char> buf(static_cast<size_t>(fin.tellg()));
            fin.seekg(0, std::ios::beg);
            fin.read(buf.data(), buf.size());
            linfo("send file start");
            auto res = c.send_data(std::move(buf), BINARY_FRAME);
            assert(res, "send file failed");
        } else if (!c.send_data(std::vector(str.data(), str.data() + str.length()), TEXT_FRAME)) {
            lerror("send data failed");
            break;
        } else {
            linfo("send data success");
        }
    }
}
\end{lstlisting}

\begin{lstlisting}[
  captionpos=b,
  caption={WebSocket++ 服务器示例},
  label={websocketpp-server-example}
]
#include <websocketpp/config/asio_no_tls.hpp>
#include <websocketpp/server.hpp>
#include <iostream>

using server = websocketpp::server<websocketpp::config::asio>;

void print_time(); // implemention omitted
int main() {
  server echo_server;
  try {
    echo_server.set_access_channels(websocketpp::log::alevel::all);
    echo_server.clear_access_channels(websocketpp::log::alevel::frame_payload);
    echo_server.set_max_message_size(1 << 30);
    echo_server.init_asio();
    echo_server.set_message_handler([&](auto hdl, auto msg) {
      print_time();
      std::cout << " received frame with size " << msg->get_payload().size()
                << std::endl;
    });
    echo_server.listen(1234);
    echo_server.start_accept();
    echo_server.run();
  } catch (const websocketpp::exception &e) {
    std::cout << e.what() << std::endl;
  }
}
\end{lstlisting}